home *** CD-ROM | disk | FTP | other *** search
- {$S-,R-,I-,V-,B-}
-
- {*********************************************************}
- {* TPTIMER.PAS 2.00 *}
- {* by TurboPower Software *}
- {*********************************************************}
-
- Unit TpTimer;
- {-Allows events to be timed With 1 microsecond resolution}
-
-
-
- Interface
- Const
- TimerResolution = 1193181.667;
- Procedure InitializeTimer;
- {-ReProgram the timer chip to allow 1 microsecond resolution}
-
- Procedure RestoreTimer;
- {-Restore the timer chip to its normal state}
-
- Function ReadTimer : LongInt;
- {-Read the timer With 1 microsecond resolution}
-
- Function ElapsedTime(Start, Stop : LongInt) : Real;
- {-Calculate time elapsed (in milliseconds) between Start and Stop}
-
- Function ElapsedTimeString(Start, Stop : LongInt) : String;
- {-Return time elapsed (in milliseconds) between Start and Stop as a String}
-
- {==========================================================================}
-
- Implementation
-
- Var
- SaveExitProc : Pointer;
- Delta : LongInt;
-
- Function Cardinal(L : LongInt) : Real;
- {-Return the unsigned equivalent of L as a Real}
- begin {Cardinal}
- if L < 0 then
- Cardinal := 4294967296.0+L
- else
- Cardinal := L;
- end; {Cardinal}
-
- Function ElapsedTime(Start, Stop : LongInt) : Real;
- {-Calculate time elapsed (in milliseconds) between Start and Stop}
- begin {ElapsedTime}
- ElapsedTime := 1000.0*Cardinal(Stop-(Start+Delta))/TimerResolution;
- end; {ElapsedTime}
-
- Function ElapsedTimeString(Start, Stop : LongInt) : String;
- {-Return time elapsed (in milliseconds) between Start and Stop as a String}
- Var
- R : Real;
- S : String;
- begin {ElapsedTimeString}
- R := ElapsedTime(Start, Stop);
- Str(R:0:3, S);
- ElapsedTimeString := S;
- end; {ElapsedTimeString}
-
- Procedure InitializeTimer;
- {-ReProgram the timer chip to allow 1 microsecond resolution}
- begin {InitializeTimer}
- {select timer mode 2, read/Write channel 0}
- Port[$43] := $34; {00110100b}
- Inline($EB/$00); {jmp short $+2 ;Delay}
- Port[$40] := $00; {LSB = 0}
- Inline($EB/$00); {jmp short $+2 ;Delay}
- Port[$40] := $00; {MSB = 0}
- end; {InitializeTimer}
-
- Procedure RestoreTimer;
- {-Restore the timer chip to its normal state}
- begin {RestoreTimer}
- {select timer mode 3, read/Write channel 0}
- Port[$43] := $36; {00110110b}
- Inline($EB/$00); {jmp short $+2 ;Delay}
- Port[$40] := $00; {LSB = 0}
- Inline($EB/$00); {jmp short $+2 ;Delay}
- Port[$40] := $00; {MSB = 0}
- end; {RestoreTimer}
-
- Function ReadTimer : LongInt;
- {-Read the timer With 1 microsecond resolution}
- begin {ReadTimer}
- Inline(
- $FA/ {cli ;Disable interrupts}
- $BA/$20/$00/ {mov dx,$20 ;Address PIC ocw3}
- $B0/$0A/ {mov al,$0A ;Ask to read irr}
- $EE/ {out dx,al}
- $B0/$00/ {mov al,$00 ;Latch timer 0}
- $E6/$43/ {out $43,al}
- $EC/ {in al,dx ;Read irr}
- $89/$C7/ {mov di,ax ;Save it in DI}
- $E4/$40/ {in al,$40 ;Counter --> bx}
- $88/$C3/ {mov bl,al ;LSB in BL}
- $E4/$40/ {in al,$40}
- $88/$C7/ {mov bh,al ;MSB in BH}
- $F7/$D3/ {not bx ;Need ascending counter}
- $E4/$21/ {in al,$21 ;Read PIC imr}
- $89/$C6/ {mov si,ax ;Save it in SI}
- $B0/$FF/ {mov al,$0FF ;Mask all interrupts}
- $E6/$21/ {out $21,al}
- $B8/$40/$00/ {mov ax,$40 ;read low Word of time}
- $8E/$C0/ {mov es,ax ;from BIOS data area}
- $26/$8B/$16/$6C/$00/ {mov dx,es:[$6C]}
- $89/$F0/ {mov ax,si ;Restore imr from SI}
- $E6/$21/ {out $21,al}
- $FB/ {sti ;Enable interrupts}
- $89/$F8/ {mov ax,di ;Retrieve old irr}
- $A8/$01/ {test al,$01 ;Counter hit 0?}
- $74/$07/ {jz done ;Jump if not}
- $81/$FB/$FF/$00/ {cmp bx,$FF ;Counter > $FF?}
- $77/$01/ {ja done ;Done if so}
- $42/ {inc dx ;else count int req.}
- {done:}
- $89/$5E/$FC/ {mov [bp-4],bx ;set Function result}
- $89/$56/$FE); {mov [bp-2],dx}
- end; {ReadTimer}
-
- Procedure Calibrate;
- {-Calibrate the timer}
- Const
- Reps = 1000;
- Var
- I : Word;
- L1, L2, Diff : LongInt;
- begin {Calibrate}
- Delta := MaxInt;
- For I := 1 to Reps do begin
- L1 := ReadTimer;
- L2 := ReadTimer;
- {use the minimum difference}
- Diff := L2-L1;
- if Diff < Delta then
- Delta := Diff;
- end;
- end; {Calibrate}
-
- {$F+}
- Procedure OurExitProc;
- {-Restore timer chip to its original state}
- begin {OurExitProc}
- ExitProc := SaveExitProc;
- RestoreTimer;
- end; {OurExitProc}
- {$F-}
-
- begin
- {set up our Exit handler}
- SaveExitProc := ExitProc;
- ExitProc := @OurExitProc;
-
- {reProgram the timer chip}
- InitializeTimer;
-
- {adjust For speed of machine}
- Calibrate;
- end.